import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import kurtosis, skew
import os
import matplotlib.ticker as ticker

# 读取Excel文件
filename = '附件2_2.xlsx'
data = pd.read_excel(filename)

# 配置中文字体显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 提取相关数据列
crop_names = data['作物名称']              # 作物名称
yield_per_acre = data['亩产量/斤']         # 亩产量/斤
cost_per_acre = data['种植成本/(元/亩)']  # 种植成本/(元/亩)
price_per_kg = data['销售单价/(元/斤)']   # 销售单价/(元/斤)

# 设置seaborn样式
sns.set(style="whitegrid", font_scale=1.2, rc={"font.sans-serif": ['SimHei'], "axes.unicode_minus": False})

# --- 1. 数据可视化 ---

# 保存图片的文件夹
output_dir = 'fig'
if not os.path.exists(output_dir):
    os.makedirs(output_dir)

# 新的颜色方案
color1 = '#1f77b4'  # 蓝色
color2 = '#ff7f0e'  # 橙色
color3 = '#2ca02c'  # 绿色

# 1.1 绘制直方图（数据分布）
plt.figure(figsize=(15, 15))

plt.subplot(3,1,1)
plt.hist(yield_per_acre, bins=30, color=color1, edgecolor='black')
plt.title('亩产量分布', fontsize=14)
plt.xlabel('亩产量（斤）')
plt.ylabel('频率')

plt.subplot(3,1,2)
plt.hist(cost_per_acre, bins=30, color=color2, edgecolor='black')
plt.title('种植成本分布', fontsize=14)
plt.xlabel('种植成本（元/亩）')
plt.ylabel('频率')

plt.subplot(3,1,3)
plt.hist(price_per_kg, bins=30, color=color3, edgecolor='black')
plt.title('销售单价分布', fontsize=14)
plt.xlabel('销售单价（元/斤）')
plt.ylabel('频率')

# 使用 MaxNLocator 自动减少纵坐标的刻度数量
plt.gca().xaxis.set_major_locator(ticker.MaxNLocator(nbins=12))  # 例如将纵坐标的刻度数量限制为6个

plt.tight_layout()
plt.savefig(os.path.join(output_dir, 'histograms.png'))  # 保存直方图
plt.show()

# 1.2 绘制箱型图（展示数据的集中趋势和离群点）
plt.figure(figsize=(10, 12))

plt.subplot(3,1,1)
sns.boxplot(yield_per_acre, color=color1)
plt.title('亩产量箱型图', fontsize=14)
plt.ylabel('亩产量（斤）')

plt.subplot(3,1,2)
sns.boxplot(cost_per_acre, color=color2)
plt.title('种植成本箱型图', fontsize=14)
plt.ylabel('种植成本（元/亩）')

plt.subplot(3, 1, 3)
sns.boxplot(price_per_kg, color=color3)
plt.title('销售单价箱型图')
plt.ylabel('销售单价（元/斤）')

# 使用 MaxNLocator 自动减少纵坐标的刻度数量
plt.gca().yaxis.set_major_locator(ticker.MaxNLocator(nbins=6))  # 例如将纵坐标的刻度数量限制为6个


plt.tight_layout()
plt.savefig(os.path.join(output_dir, 'boxplots.png'))  # 保存箱型图
plt.show()

# 优化散点图布局的代码
plt.figure(figsize=(16, 16))  # 调整整体图像的大小

# 调整每个子图的布局
plt.subplot(2, 2, 1)
plt.scatter(yield_per_acre, cost_per_acre, color=color1, alpha=0.7, edgecolors='w', s=100)
plt.title('亩产量 vs 种植成本', fontsize=14)
plt.xlabel('亩产量（斤）')
plt.ylabel('种植成本（元/亩）')

plt.subplot(2, 2, 2)
plt.scatter(yield_per_acre, price_per_kg, color=color2, alpha=0.7, edgecolors='w', s=100)
plt.title('亩产量 vs 销售单价', fontsize=14)
plt.xlabel('亩产量（斤）')
plt.ylabel('销售单价（元/斤）')
# 使用 MaxNLocator 自动减少纵坐标的刻度数量
plt.gca().yaxis.set_major_locator(ticker.MaxNLocator(nbins=6))  # 例如将纵坐标的刻度数量限制为6个

plt.subplot(2, 2, 3)
plt.scatter(cost_per_acre, price_per_kg, color=color3, alpha=0.7, edgecolors='w', s=100)
plt.title('种植成本 vs 销售单价', fontsize=14)
plt.xlabel('种植成本（元/亩）')
plt.ylabel('销售单价（元/斤）')

# 使用 MaxNLocator 自动减少纵坐标的刻度数量
plt.gca().yaxis.set_major_locator(ticker.MaxNLocator(nbins=6))  # 例如将纵坐标的刻度数量限制为6个
# 调整子图的间距，避免过度紧凑
plt.subplots_adjust(wspace=0.3, hspace=0.4)

# 保存图像并显示
plt.tight_layout()
plt.savefig(os.path.join(output_dir, 'scatterplots_adjusted.png'))  # 保存调整后的散点图
plt.show()

# --- 2. 描述性分析 ---

# 定义函数来处理带范围的字符串，并取均值
def convert_to_mean(value):
    if isinstance(value, str) and '-' in value:
        # 将字符串按照 '-' 拆分为两个数值，然后取均值
        parts = value.split('-')
        try:
            numbers = [float(part) for part in parts]
            return np.mean(numbers)
        except ValueError:
            return np.nan  # 如果转换失败则返回 NaN
    else:
        try:
            return float(value)
        except ValueError:
            return np.nan  # 如果不是数值则返回 NaN

# 应用转换函数到 '销售单价/(元/斤)' 列
price_per_kg = data['销售单价/(元/斤)'].apply(convert_to_mean)

# 确保其他列也是数值类型
yield_per_acre = pd.to_numeric(data['亩产量/斤'], errors='coerce')
cost_per_acre = pd.to_numeric(data['种植成本/(元/亩)'], errors='coerce')

# 计算均值, 中位数, 标准差, 峰度, 偏度
desc_stats = {
    '亩产量': {
        '均值': np.mean(yield_per_acre),
        '中位数': np.median(yield_per_acre),
        '标准差': np.std(yield_per_acre),
        '峰度': kurtosis(yield_per_acre),
        '偏度': skew(yield_per_acre)
    },
    '种植成本': {
        '均值': np.mean(cost_per_acre),
        '中位数': np.median(cost_per_acre),
        '标准差': np.std(cost_per_acre),
        '峰度': kurtosis(cost_per_acre),
        '偏度': skew(cost_per_acre)
    },
    '销售单价': {
        '均值': np.mean(price_per_kg),
        '中位数': np.median(price_per_kg),
        '标准差': np.std(price_per_kg),
        '峰度': kurtosis(price_per_kg),
        '偏度': skew(price_per_kg)
    }
}

# 打印描述性统计结果
print('--- 描述性分析 ---')
for key, stats in desc_stats.items():
    print(f'{key}: 均值={stats["均值"]:.2f}, 中位数={stats["中位数"]:.2f}, 标准差={stats["标准差"]:.2f}, '
          f'峰度={stats["峰度"]:.2f}, 偏度={stats["偏度"]:.2f}')

# --- 3. 相关性分析 ---
# 计算相关系数
correlations = {
    '亩产量与种植成本': yield_per_acre.corr(cost_per_acre),
    '亩产量与销售单价': yield_per_acre.corr(price_per_kg),
    '种植成本与销售单价': cost_per_acre.corr(price_per_kg)
}

# 打印相关性分析结果
print('--- 相关性分析 ---')
for key, corr in correlations.items():
    print(f'{key}的相关系数: {corr:.2f}')

# 创建 DataFrame
df = pd.DataFrame({
    '作物名称': crop_names,
    '亩产量': yield_per_acre,
    '种植成本': cost_per_acre,
    '销售单价': price_per_kg
})

# 绘制成对关系图
sns.pairplot(df[['亩产量', '种植成本', '销售单价']], diag_kind='kde', plot_kws={'alpha':0.6})
plt.suptitle('成对关系图', y=1.0, fontsize=16, fontweight='bold')
plt.savefig(os.path.join(output_dir, 'pairplot.png'))  # 保存图像到fig文件夹
plt.show()

# 计算相关系数矩阵
correlation_matrix = df[['亩产量', '种植成本', '销售单价']].corr()

# 绘制热力图
plt.figure(figsize=(8, 6))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0, linewidths=0.5, fmt='.2f')
plt.title('变量相关性热力图', fontsize=16, fontweight='bold')
plt.savefig(os.path.join(output_dir, 'correlation_heatmap.png'))  # 保存图像到fig文件夹
plt.show()

# 绘制累积密度图
plt.figure(figsize=(10, 6))
sns.ecdfplot(yield_per_acre, label='亩产量', color=color1)
sns.ecdfplot(cost_per_acre, label='种植成本', color=color2)
sns.ecdfplot(price_per_kg, label='销售单价', color=color3)
plt.title('累积密度图', fontsize=16, fontweight='bold')
plt.xlabel('值')
plt.ylabel('累积概率')
plt.legend()
plt.grid(True, linestyle='--', alpha=0.6)
plt.savefig(os.path.join(output_dir, 'cdf_plots.png'))  # 保存图像到fig文件夹
plt.show()


# 绘制对比图
plt.figure(figsize=(15, 10))

# 直方图
plt.subplot(2, 3, 1)
plt.hist(yield_per_acre, bins=30, color=color1, edgecolor='black')
plt.title('亩产量直方图')
plt.xlabel('亩产量（斤）')
plt.ylabel('频率')

plt.subplot(2, 3, 2)
plt.hist(cost_per_acre, bins=30, color=color2, edgecolor='black')
plt.title('种植成本直方图')
plt.xlabel('种植成本（元/亩）')
plt.ylabel('频率')

plt.subplot(2, 3, 3)
plt.hist(price_per_kg, bins=30, color=color3, edgecolor='black')
plt.title('销售单价直方图')
plt.xlabel('销售单价（元/斤）')
plt.ylabel('频率')

# 箱型图
plt.subplot(2, 3, 4)
sns.boxplot(yield_per_acre, color=color1)
plt.title('亩产量箱型图')
plt.ylabel('亩产量（斤）')

plt.subplot(2, 3, 5)
sns.boxplot(cost_per_acre, color=color2)
plt.title('种植成本箱型图')
plt.ylabel('种植成本（元/亩）')

plt.subplot(2, 3, 6)
sns.boxplot(price_per_kg, color=color3)
plt.title('销售单价箱型图')
plt.ylabel('销售单价（元/斤）')

plt.tight_layout()
plt.savefig(os.path.join(output_dir, 'histogram_boxplot_comparison.png'))  # 保存图像到fig文件夹
plt.show()
